"""
企业级金融数据MCP服务系统 - 核心异常处理
提供统一的异常定义、错误处理和异常监控
"""

import logging
import traceback
from typing import Optional, Dict, Any
from enum import Enum


class ErrorCode(Enum):
    """错误代码枚举"""
    # 系统级错误 (1000-1999)
    SYSTEM_ERROR = 1000
    CONFIG_ERROR = 1001
    DATABASE_ERROR = 1002
    DATABASE_CONNECTION_ERROR = 1003
    DATABASE_OPERATION_ERROR = 1004
    CACHE_ERROR = 1005
    CACHE_CONNECTION_ERROR = 1006
    CACHE_OPERATION_ERROR = 1007
    NETWORK_ERROR = 1008
    
    # 数据相关错误 (2000-2999)
    DATA_NOT_FOUND = 2000
    DATA_INVALID = 2001
    DATA_SYNC_ERROR = 2002
    DATA_QUALITY_ERROR = 2003
    DATA_SOURCE_ERROR = 2004
    
    # 业务逻辑错误 (3000-3999)
    BUSINESS_LOGIC_ERROR = 3000
    VALIDATION_ERROR = 3001
    PERMISSION_DENIED = 3002
    RATE_LIMIT_EXCEEDED = 3003
    
    # MCP服务错误 (4000-4999)
    MCP_SERVICE_ERROR = 4000
    TOOL_EXECUTION_ERROR = 4001
    RESOURCE_ACCESS_ERROR = 4002
    PROTOCOL_ERROR = 4003
    
    # 外部服务错误 (5000-5999)
    EXTERNAL_API_ERROR = 5000
    AKSHARE_ERROR = 5001
    THIRD_PARTY_ERROR = 5002


class BaseFinancialMCPException(Exception):
    """金融MCP服务基础异常类"""
    
    def __init__(
        self,
        message: str,
        error_code: ErrorCode,
        details: Optional[Dict[str, Any]] = None,
        cause: Optional[Exception] = None
    ):
        super().__init__(message)
        self.message = message
        self.error_code = error_code
        self.details = details or {}
        self.cause = cause
        self.timestamp = None
        
        # 记录异常日志
        self._log_exception()
    
    def _log_exception(self):
        """记录异常日志"""
        logger = logging.getLogger(self.__class__.__name__)
        
        log_data = {
            "error_code": self.error_code.value,
            "message": self.message,
            "details": self.details
        }
        
        if self.cause:
            log_data["cause"] = str(self.cause)
            log_data["traceback"] = traceback.format_exc()
        
        logger.error(f"异常发生: {log_data}")
    
    def to_dict(self) -> Dict[str, Any]:
        """转换为字典格式"""
        return {
            "error_code": self.error_code.value,
            "error_name": self.error_code.name,
            "message": self.message,
            "details": self.details,
            "timestamp": self.timestamp
        }


class SystemException(BaseFinancialMCPException):
    """系统级异常"""
    
    def __init__(self, message: str, details: Optional[Dict[str, Any]] = None, cause: Optional[Exception] = None):
        super().__init__(message, ErrorCode.SYSTEM_ERROR, details, cause)


class ConfigException(BaseFinancialMCPException):
    """配置异常"""
    
    def __init__(self, message: str, details: Optional[Dict[str, Any]] = None, cause: Optional[Exception] = None):
        super().__init__(message, ErrorCode.CONFIG_ERROR, details, cause)


class DatabaseException(BaseFinancialMCPException):
    """数据库异常"""
    
    def __init__(self, message: str, details: Optional[Dict[str, Any]] = None, cause: Optional[Exception] = None):
        super().__init__(message, ErrorCode.DATABASE_ERROR, details, cause)


class DatabaseConnectionError(BaseFinancialMCPException):
    """数据库连接错误"""
    
    def __init__(self, message: str, details: Optional[Dict[str, Any]] = None, cause: Optional[Exception] = None):
        super().__init__(message, ErrorCode.DATABASE_CONNECTION_ERROR, details, cause)


class DatabaseOperationError(BaseFinancialMCPException):
    """数据库操作错误"""
    
    def __init__(self, message: str, details: Optional[Dict[str, Any]] = None, cause: Optional[Exception] = None):
        super().__init__(message, ErrorCode.DATABASE_OPERATION_ERROR, details, cause)


class CacheException(BaseFinancialMCPException):
    """缓存异常"""
    
    def __init__(self, message: str, details: Optional[Dict[str, Any]] = None, cause: Optional[Exception] = None):
        super().__init__(message, ErrorCode.CACHE_ERROR, details, cause)


class CacheConnectionError(BaseFinancialMCPException):
    """缓存连接错误"""
    
    def __init__(self, message: str, details: Optional[Dict[str, Any]] = None, cause: Optional[Exception] = None):
        super().__init__(message, ErrorCode.CACHE_CONNECTION_ERROR, details, cause)


class CacheOperationError(BaseFinancialMCPException):
    """缓存操作错误"""
    
    def __init__(self, message: str, details: Optional[Dict[str, Any]] = None, cause: Optional[Exception] = None):
        super().__init__(message, ErrorCode.CACHE_OPERATION_ERROR, details, cause)


class NetworkException(BaseFinancialMCPException):
    """网络异常"""
    
    def __init__(self, message: str, details: Optional[Dict[str, Any]] = None, cause: Optional[Exception] = None):
        super().__init__(message, ErrorCode.NETWORK_ERROR, details, cause)


class DataNotFoundException(BaseFinancialMCPException):
    """数据未找到异常"""
    
    def __init__(self, message: str, details: Optional[Dict[str, Any]] = None, cause: Optional[Exception] = None):
        super().__init__(message, ErrorCode.DATA_NOT_FOUND, details, cause)


class DataInvalidException(BaseFinancialMCPException):
    """数据无效异常"""
    
    def __init__(self, message: str, details: Optional[Dict[str, Any]] = None, cause: Optional[Exception] = None):
        super().__init__(message, ErrorCode.DATA_INVALID, details, cause)


class DataSyncException(BaseFinancialMCPException):
    """数据同步异常"""
    
    def __init__(self, message: str, details: Optional[Dict[str, Any]] = None, cause: Optional[Exception] = None):
        super().__init__(message, ErrorCode.DATA_SYNC_ERROR, details, cause)


class DataQualityException(BaseFinancialMCPException):
    """数据质量异常"""
    
    def __init__(self, message: str, details: Optional[Dict[str, Any]] = None, cause: Optional[Exception] = None):
        super().__init__(message, ErrorCode.DATA_QUALITY_ERROR, details, cause)


class DataSourceException(BaseFinancialMCPException):
    """数据源异常"""
    
    def __init__(self, message: str, details: Optional[Dict[str, Any]] = None, cause: Optional[Exception] = None):
        super().__init__(message, ErrorCode.DATA_SOURCE_ERROR, details, cause)


class BusinessLogicException(BaseFinancialMCPException):
    """业务逻辑异常"""
    
    def __init__(self, message: str, details: Optional[Dict[str, Any]] = None, cause: Optional[Exception] = None):
        super().__init__(message, ErrorCode.BUSINESS_LOGIC_ERROR, details, cause)


class ValidationException(BaseFinancialMCPException):
    """验证异常"""
    
    def __init__(self, message: str, details: Optional[Dict[str, Any]] = None, cause: Optional[Exception] = None):
        super().__init__(message, ErrorCode.VALIDATION_ERROR, details, cause)


class PermissionDeniedException(BaseFinancialMCPException):
    """权限拒绝异常"""
    
    def __init__(self, message: str, details: Optional[Dict[str, Any]] = None, cause: Optional[Exception] = None):
        super().__init__(message, ErrorCode.PERMISSION_DENIED, details, cause)


class RateLimitExceededException(BaseFinancialMCPException):
    """速率限制超出异常"""
    
    def __init__(self, message: str, details: Optional[Dict[str, Any]] = None, cause: Optional[Exception] = None):
        super().__init__(message, ErrorCode.RATE_LIMIT_EXCEEDED, details, cause)


class MCPServiceException(BaseFinancialMCPException):
    """MCP服务异常"""
    
    def __init__(self, message: str, details: Optional[Dict[str, Any]] = None, cause: Optional[Exception] = None):
        super().__init__(message, ErrorCode.MCP_SERVICE_ERROR, details, cause)


class ToolExecutionException(BaseFinancialMCPException):
    """工具执行异常"""
    
    def __init__(self, message: str, details: Optional[Dict[str, Any]] = None, cause: Optional[Exception] = None):
        super().__init__(message, ErrorCode.TOOL_EXECUTION_ERROR, details, cause)


class ResourceAccessException(BaseFinancialMCPException):
    """资源访问异常"""
    
    def __init__(self, message: str, details: Optional[Dict[str, Any]] = None, cause: Optional[Exception] = None):
        super().__init__(message, ErrorCode.RESOURCE_ACCESS_ERROR, details, cause)


class ProtocolException(BaseFinancialMCPException):
    """协议异常"""
    
    def __init__(self, message: str, details: Optional[Dict[str, Any]] = None, cause: Optional[Exception] = None):
        super().__init__(message, ErrorCode.PROTOCOL_ERROR, details, cause)


class ExternalAPIException(BaseFinancialMCPException):
    """外部API异常"""
    
    def __init__(self, message: str, details: Optional[Dict[str, Any]] = None, cause: Optional[Exception] = None):
        super().__init__(message, ErrorCode.EXTERNAL_API_ERROR, details, cause)


class AkshareException(BaseFinancialMCPException):
    """Akshare异常"""
    
    def __init__(self, message: str, details: Optional[Dict[str, Any]] = None, cause: Optional[Exception] = None):
        super().__init__(message, ErrorCode.AKSHARE_ERROR, details, cause)


class ThirdPartyException(BaseFinancialMCPException):
    """第三方服务异常"""
    
    def __init__(self, message: str, details: Optional[Dict[str, Any]] = None, cause: Optional[Exception] = None):
        super().__init__(message, ErrorCode.THIRD_PARTY_ERROR, details, cause)


class ExceptionHandler:
    """异常处理器"""
    
    def __init__(self):
        self.logger = logging.getLogger(self.__class__.__name__)
    
    def handle_exception(self, exception: Exception) -> Dict[str, Any]:
        """处理异常并返回标准化响应"""
        if isinstance(exception, BaseFinancialMCPException):
            return self._handle_custom_exception(exception)
        else:
            return self._handle_unknown_exception(exception)
    
    def _handle_custom_exception(self, exception: BaseFinancialMCPException) -> Dict[str, Any]:
        """处理自定义异常"""
        return {
            "success": False,
            "error": exception.to_dict(),
            "data": None
        }
    
    def _handle_unknown_exception(self, exception: Exception) -> Dict[str, Any]:
        """处理未知异常"""
        self.logger.error(f"未知异常: {exception}", exc_info=True)
        
        return {
            "success": False,
            "error": {
                "error_code": ErrorCode.SYSTEM_ERROR.value,
                "error_name": ErrorCode.SYSTEM_ERROR.name,
                "message": "系统内部错误",
                "details": {
                    "original_error": str(exception),
                    "type": type(exception).__name__
                }
            },
            "data": None
        }
    
    def wrap_async_function(self, func):
        """异步函数异常包装装饰器"""
        async def wrapper(*args, **kwargs):
            try:
                return await func(*args, **kwargs)
            except Exception as e:
                return self.handle_exception(e)
        return wrapper
    
    def wrap_sync_function(self, func):
        """同步函数异常包装装饰器"""
        def wrapper(*args, **kwargs):
            try:
                return func(*args, **kwargs)
            except Exception as e:
                return self.handle_exception(e)
        return wrapper


# 全局异常处理器实例
exception_handler = ExceptionHandler()


def handle_exceptions(func):
    """异常处理装饰器"""
    if hasattr(func, '__code__') and func.__code__.co_flags & 0x80:  # 检查是否为协程
        return exception_handler.wrap_async_function(func)
    else:
        return exception_handler.wrap_sync_function(func)


def raise_for_error_code(error_code: ErrorCode, message: str, details: Optional[Dict[str, Any]] = None):
    """根据错误代码抛出对应异常"""
    exception_mapping = {
        ErrorCode.SYSTEM_ERROR: SystemException,
        ErrorCode.CONFIG_ERROR: ConfigException,
        ErrorCode.DATABASE_ERROR: DatabaseException,
        ErrorCode.DATABASE_CONNECTION_ERROR: DatabaseConnectionError,
        ErrorCode.DATABASE_OPERATION_ERROR: DatabaseOperationError,
        ErrorCode.CACHE_ERROR: CacheException,
        ErrorCode.CACHE_CONNECTION_ERROR: CacheConnectionError,
        ErrorCode.CACHE_OPERATION_ERROR: CacheOperationError,
        ErrorCode.NETWORK_ERROR: NetworkException,
        ErrorCode.DATA_NOT_FOUND: DataNotFoundException,
        ErrorCode.DATA_INVALID: DataInvalidException,
        ErrorCode.DATA_SYNC_ERROR: DataSyncException,
        ErrorCode.DATA_QUALITY_ERROR: DataQualityException,
        ErrorCode.DATA_SOURCE_ERROR: DataSourceException,
        ErrorCode.BUSINESS_LOGIC_ERROR: BusinessLogicException,
        ErrorCode.VALIDATION_ERROR: ValidationException,
        ErrorCode.PERMISSION_DENIED: PermissionDeniedException,
        ErrorCode.RATE_LIMIT_EXCEEDED: RateLimitExceededException,
        ErrorCode.MCP_SERVICE_ERROR: MCPServiceException,
        ErrorCode.TOOL_EXECUTION_ERROR: ToolExecutionException,
        ErrorCode.RESOURCE_ACCESS_ERROR: ResourceAccessException,
        ErrorCode.PROTOCOL_ERROR: ProtocolException,
        ErrorCode.EXTERNAL_API_ERROR: ExternalAPIException,
        ErrorCode.AKSHARE_ERROR: AkshareException,
        ErrorCode.THIRD_PARTY_ERROR: ThirdPartyException,
    }
    
    exception_class = exception_mapping.get(error_code, SystemException)
    raise exception_class(message, details)